﻿using System;
using System.Data;
using System.Data.OleDb;

namespace GestorMultimedia
{
    public sealed class TConexionOleDb : TConexion
    {



        private OleDbCommand CInsert = null, CUpdate = null, CDelete = null;

        protected override void CrearComandoInsert(DataTable t)
        {
            string NombreParametro = "", NombreColumna = "";
            Int32 longitud = 0;
            OleDbType TipoOleDb = 0;
            string SentenciaSQL = "";

            CInsert = new OleDbCommand();
            CInsert.CommandType = CommandType.Text;

            //"INSERT INTO  PELICULAS (Id,Titulo,TOriginal,Anno,Ficcion,Animacion,Comentarios,Sinopsis) VALUES (?,?,?,?,?,?,?,?)";
            SentenciaSQL = "INSERT INTO" + " " + t.TableName + " ("; //Creacion de la primera parte de la sentencia SQL 

            //Creacion de los parámetros del comando
            foreach (DataColumn columna in t.Columns)
            {
                //Para cada columna de la tabla creamos un parámetro para CInsert
                NombreColumna = columna.ColumnName;
                NombreParametro = "@" + NombreColumna;

                SentenciaSQL = SentenciaSQL + NombreColumna + ",";//Añadimos el nombre del campo a la sentencia SQL

                if (columna.DataType.FullName == "System.Int32")
                {
                    TipoOleDb = OleDbType.Integer;
                    longitud = sizeof(System.Int32);
                }
                else if (columna.DataType.FullName == "System.UInt32")
                {
                    TipoOleDb = OleDbType.UnsignedInt;
                    longitud = sizeof(System.UInt32);
                }
                else if (columna.DataType.FullName == "System.String")
                {
                    TipoOleDb = OleDbType.WChar;
                    longitud = 255;
                }
                else if (columna.DataType.FullName == "System.Boolean")
                {
                    TipoOleDb = OleDbType.Boolean;
                    longitud = sizeof(System.Boolean); ;
                }
                else if (columna.DataType.FullName == "System.DateTime")
                {
                    TipoOleDb = OleDbType.Date;
                    longitud = 8;


                }

                CInsert.Parameters.Add(NombreParametro, TipoOleDb, longitud, NombreColumna);
            }

            //quita la coma que se cuela en la sentencia cuando se añade el nombre de la ultima columna
            SentenciaSQL = SentenciaSQL.Substring(0, SentenciaSQL.Length - 1);

            SentenciaSQL = SentenciaSQL + ") VALUES (";//construimos otra parte de la sentecia SQL

            //Añadimos los ? necesarios para completar la sentencia SQL
            for (int cont = 0; cont <= t.Columns.Count - 1; cont++)
            {
                SentenciaSQL = SentenciaSQL + "?,";
            }

            //quita la coma que se cuela en la sentencia cuando se añade el ultimo ? correspondiente al último parámetro
            SentenciaSQL = SentenciaSQL.Substring(0, SentenciaSQL.Length - 1);

            SentenciaSQL = SentenciaSQL + ")";//Completamos la sentencia SQL

            CInsert.CommandText = SentenciaSQL;
            

        }

        protected override void CrearComandoUpdate(DataTable t)
        {
            string NombreParametro = "";
            Int32 longitud = 0;
            OleDbType TipoOleDb = 0;
            string SentenciaSQL = "";
            bool EsClave = true;

            //comando.CommandText = "UPDATE PELICULAS SET Titulo=?,TOriginal=?,Anno=?,Ficcion=?,Animacion=?,Comentarios=?,Sinopsis=? WHERE (Id=?)";

            CUpdate = new OleDbCommand();
            CUpdate.CommandType = CommandType.Text;

            SentenciaSQL = "UPDATE " + t.TableName + " SET ";

            foreach (DataColumn columna in t.Columns)
            {
                EsClave = false;
                foreach (DataColumn col in t.PrimaryKey)
                {
                    if (col.ColumnName == columna.ColumnName)
                    {
                        EsClave = true;
                        break;
                    }
                }
                if (EsClave == false)
                {
                    NombreParametro = "@" + columna.ColumnName;
                    SentenciaSQL = SentenciaSQL + columna.ColumnName + "=?,";
                    if (columna.DataType.FullName == "System.Int32")
                    {
                        TipoOleDb = OleDbType.Integer;
                        longitud = sizeof(System.Int32);
                    }
                    else if (columna.DataType.FullName == "System.UInt32")
                    {
                        TipoOleDb = OleDbType.UnsignedInt;
                        longitud = sizeof(System.UInt32);
                    }
                    else if (columna.DataType.FullName == "System.String")
                    {
                        TipoOleDb = OleDbType.WChar;
                        longitud = 255;
                    }
                    else if (columna.DataType.FullName == "System.Boolean")
                    {
                        TipoOleDb = OleDbType.Boolean;
                        longitud = sizeof(System.Boolean); ;
                    }
                    else if (columna.DataType.FullName == "System.DateTime")
                    {
                        TipoOleDb = OleDbType.Date;
                        longitud = 8;
                    }
                    CUpdate.Parameters.Add(NombreParametro, TipoOleDb, longitud, columna.ColumnName);
                }
            }
            SentenciaSQL = SentenciaSQL.Substring(0, SentenciaSQL.Length - 1);
            SentenciaSQL = SentenciaSQL + " WHERE ";
            foreach (DataColumn columna in t.PrimaryKey)
            {
                NombreParametro = "@" + columna.ColumnName;
                SentenciaSQL = SentenciaSQL + "(" + columna.ColumnName + "=?) AND ";
                if (columna.DataType.FullName == "System.Int32")
                {
                    TipoOleDb = OleDbType.Integer;
                    longitud = sizeof(System.Int32);
                }
                else if (columna.DataType.FullName == "System.String")
                {
                    TipoOleDb = OleDbType.WChar;
                    longitud = 255;
                }
                else if (columna.DataType.FullName == "System.Boolean")
                {
                    TipoOleDb = OleDbType.Boolean;
                    longitud = sizeof(System.Boolean); ;
                }
                else if (columna.DataType.FullName == "System.DateTime")
                {
                    TipoOleDb = OleDbType.Date;
                    longitud = 8;
                }
                CUpdate.Parameters.Add(NombreParametro, TipoOleDb, longitud, columna.ColumnName);
            }
            SentenciaSQL = SentenciaSQL.Substring(0, SentenciaSQL.Length - 4);
            CUpdate.CommandText = SentenciaSQL;

            

        }

        protected override void CrearComandoDelete(DataTable t)
        {
            string NombreParametro = "";
            Int32 longitud = 0;
            OleDbType TipoOleDb = 0;
            string SentenciaSQL = "";
            DataColumn[] ClavesPrimarias;
            //comando.CommandText = "DELETE FROM PELICULAS WHERE Id = ?";

            CDelete = new OleDbCommand();
            CDelete.CommandType = CommandType.Text;

            SentenciaSQL = "DELETE FROM " + t.TableName + " WHERE (";

            ClavesPrimarias = t.PrimaryKey;
            NombreParametro = ClavesPrimarias[0].ColumnName;
            foreach (DataColumn columna in ClavesPrimarias)
            {
                
                NombreParametro = "@" + columna.ColumnName;
                SentenciaSQL = SentenciaSQL + columna.ColumnName + " = ? AND ";
                if (columna.DataType.FullName == "System.Int32")
                {
                    TipoOleDb = OleDbType.Integer;
                    longitud = sizeof(System.Int32);
                }
                else if (columna.DataType.FullName == "System.UInt32")
                {
                    TipoOleDb = OleDbType.UnsignedInt;
                    longitud = sizeof(System.UInt32);
                }
                else if (columna.DataType.FullName == "System.String")
                {
                    TipoOleDb = OleDbType.WChar;
                    longitud = 255;
                }
                else if (columna.DataType.FullName == "System.Boolean")
                {
                    TipoOleDb = OleDbType.Boolean;
                    longitud = sizeof(System.Boolean); ;
                }
                else if (columna.DataType.FullName == "System.DateTime")
                {
                    TipoOleDb = OleDbType.Date;
                    longitud = 8;
                }
                CDelete.Parameters.Add(NombreParametro, TipoOleDb, longitud, columna.ColumnName);
            }

            SentenciaSQL = SentenciaSQL.Substring(0, SentenciaSQL.Length - 4);
            SentenciaSQL = SentenciaSQL + ")";
            CDelete.CommandText = SentenciaSQL;

            
        }

        public TConexionOleDb(string BBDD)
        {
            Log = new TLogOperaciones();
            this.RutaDatos = BBDD;
        }

        /*~TConexionOleDb()
        {
            ObjLiberado = true;
            this.Dispose();
        }*/

        public override void Iniciar()
        {

        }

        /*public override void Dispose()
        {
            //Aqui se liberan los recursos
            ListaCamposComparacion = null;
            Log.Dispose();
            Log = null;

            if(CInsert!=null)
                CInsert.Dispose();
            if(CUpdate!=null)
                CUpdate.Dispose();
            if(CDelete!=null)
                CDelete.Dispose();

            if (ObjLiberado == false)//si no es el destructor el que ha invocado al dipose
                GC.SuppressFinalize(this);//se indica al GC que no es necesario llamar al destructor de este objeto
        }*/

        public override bool ProbarConexion()
        {
            OleDbConnection Conexion;


            if (this.RutaDatos != "")
            {
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + this.RutaDatos; ;
                try
                {
                    Conexion.Open();
                    Conexion.Close();
                    
                    this.ResultOp = true;
                }
                catch (OleDbException ex)
                {
                    this.ResultOp = false;
                    
                }
            }
            else
            {
                this.ResultOp = false;
                
            }

            return ResultOp;
        }

        public override DataTable Leer(string NombreTabla)
        {
            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;
            OleDbCommand CSelect;
            DataTable t = null;


            this.ResultOp = false;
            if (this.ProbarConexion() == true)
            {
                

                //crear objeto conexion y asignarle la cadena de conexion
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OrigenDatos + ";Persist Security Info=False"; ;

                //Crear comando CSelect y asignarle el objeto conexion
                CSelect = new OleDbCommand();
                CSelect.Connection = Conexion;

                //Crear adaptador y asignarle el comando select
                Adaptador = new OleDbDataAdapter();
                Adaptador.SelectCommand = CSelect;
                //Usar el adaptador para llenar el dataset almacen con las tablas que gestionan los artistas
                t = new DataTable();

                CSelect.CommandType = CommandType.Text;

                CSelect.CommandText = "select * from " + NombreTabla;
                Adaptador.Fill(t);

                
                //CSelect.Dispose();
                //Conexion.Dispose();
                //Adaptador.Dispose();

                this.ResultOp = true;
            }
            

            return t;
        }

        public override void Sincronizar(DataTable t)
        {
            DataTable tAux = null;
            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;


            this.ResultOp = false;
            this.CInsert = null;
            this.CUpdate = null;
            this.CDelete = null;


            //crear objeto conexion 
            Conexion = new OleDbConnection();
            Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + this.RutaDatos + ";Persist Security Info=False"; ;

            //Crear adaptador 
            Adaptador = new OleDbDataAdapter();

            //Llamar al método GetChanges para crear un segundo DataSet que sólo incorpore los cambios realizados en los datos.
            tAux = t.GetChanges();


            if (tAux != null)
            {
                if (this.ProbarConexion() == true)
                {
                    tAux.TableName = t.TableName;
                    this.CrearComandoDelete(tAux);
                    this.CDelete.Connection = Conexion;
                    this.CrearComandoInsert(tAux);
                    this.CInsert.Connection = Conexion;
                    this.CrearComandoUpdate(tAux);
                    this.CUpdate.Connection = Conexion;

                    Adaptador.DeleteCommand = CDelete;
                    Adaptador.UpdateCommand = CUpdate;
                    Adaptador.InsertCommand = CInsert;

                    Adaptador.Update(tAux);

                    
                    /*this.CUpdate.Dispose();
                    this.CUpdate = null;
                    this.CDelete.Dispose();
                    this.CDelete = null;
                    this.CInsert.Dispose();
                    this.CInsert = null;
                    Conexion.Dispose();
                    Conexion = null;
                    Adaptador.Dispose();
                    Adaptador = null;*/
                    this.ResultOp = true;
                }                
            }
            else
            {
                ResultOp = true;

            }
        }

        public override void Ejecutar(string SentenciaSQL)
        {
            OleDbConnection Conexion;
            OleDbCommand comando;

            if (this.RutaDatos != "")
            {
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + this.RutaDatos; ;
                try
                {
                    comando = new OleDbCommand(SentenciaSQL);
                    comando.Connection = Conexion;
                    Conexion.Open();
                    comando.ExecuteNonQuery();
                    Conexion.Close();
                    //comando.Dispose();
                    //comando = null;
                    //Conexion.Dispose();
                    //Conexion = null;

                    this.ResultOp = true;
                   
                }
                catch (OleDbException ex)
                {
                    this.ResultOp = false;               
                }
            }
            else
            {
                this.ResultOp = false;
            }
        }




        /*public override DataTable LeerTodo(string NombreTabla, string[] campos)
        {

            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;
            OleDbCommand CSelect;
            DataTable t = null;
            

            this.ResultOp = false;
            if (this.ProbarConexion() == true)
            {


                //crear objeto conexion y asignarle la cadena de conexion
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OrigenDatos + ";Persist Security Info=False"; ;

                //Crear comando CSelect y asignarle el objeto conexion
                CSelect = new OleDbCommand();
                CSelect.Connection = Conexion;

                //Crear adaptador y asignarle el comando select
                Adaptador = new OleDbDataAdapter();
                Adaptador.SelectCommand = CSelect;
                //Usar el adaptador para llenar el dataset almacen con las tablas que gestionan los artistas
                t = new DataTable();

                CSelect.CommandType = CommandType.Text;
                CSelect.CommandText = "select ";
                if (campos != null)
                {
                    for (int cont = 0; cont <= campos.Length - 1; cont++)
                    {
                        CSelect.CommandText = CSelect.CommandText + campos[cont] + ",";
                    }
                    CSelect.CommandText = CSelect.CommandText.Substring(0, CSelect.CommandText.Length - 1);
                    CSelect.CommandText = CSelect.CommandText + " from " + NombreTabla;
                }
                else
                    CSelect.CommandText = CSelect.CommandText + " * from " + NombreTabla;

                Adaptador.Fill(t);


                CSelect.Dispose();
                Conexion.Dispose();
                Adaptador.Dispose();

                this.ResultOp = true;
            }


            return t;
        }*/

        /* public override DataRow Leer(string NombreTabla, string NombreCampoId,UInt32 Id)
        {

            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;
            OleDbCommand CSelect;
            DataTable t = null;
            DataRow f=null;


            this.ResultOp = false;
            if (this.ProbarConexion() == true)
            {


                //crear objeto conexion y asignarle la cadena de conexion
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OrigenDatos + ";Persist Security Info=False"; ;

                //Crear comando CSelect y asignarle el objeto conexion
                CSelect = new OleDbCommand();
                CSelect.Connection = Conexion;

                //Crear adaptador y asignarle el comando select
                Adaptador = new OleDbDataAdapter();
                Adaptador.SelectCommand = CSelect;
                //Usar el adaptador para llenar el dataset almacen con las tablas que gestionan los artistas
                t = new DataTable();

                CSelect.CommandType = CommandType.Text;

                CSelect.CommandText = "select * from " + NombreTabla + " where " + NombreCampoId + " = " + Id.ToString();
                Adaptador.Fill(t);

                if(t.Rows.Count==1)
                    f = t.Rows[0];

                CSelect.Dispose();
                Conexion.Dispose();
                Adaptador.Dispose();


                this.ResultOp = true;
            }


            return f;
        }*/

        /*public override UInt32 ValorMaximo(string Tabla,string campo)
        {

            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;
            OleDbCommand CSelect;
            DataTable t = null;
           

            ResultOp = false;
            if (this.ProbarConexion() == true)
            {


                //crear objeto conexion y asignarle la cadena de conexion
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OrigenDatos + ";Persist Security Info=False"; ;

                //Crear comando CSelect y asignarle el objeto conexion
                CSelect = new OleDbCommand();
                CSelect.Connection = Conexion;

                //Crear adaptador y asignarle el comando select
                Adaptador = new OleDbDataAdapter();
                Adaptador.SelectCommand = CSelect;
                //Usar el adaptador para llenar el dataset almacen con las tablas que gestionan los artistas
                t = new DataTable();

                CSelect.CommandType = CommandType.Text;

                CSelect.CommandText = "select MAX(" +  campo + ")" + " from " + Tabla;
                Adaptador.Fill(t);

                CSelect.Dispose();
                Conexion.Dispose();
                Adaptador.Dispose();

                ResultOp = true;

                if (t.Rows.Count == 1)
                    return Convert.ToUInt32(t.Rows[0][campo]);
                else
                    return 2;

                
            }
            else
                return 2;
        }*/

        /*public override bool Esta(string Tabla, DataRow fila, string[] campos)
        {
            //devuelve true si la fila esta en origen
            //Construir el comando select. Select * from Tabla where (campo1=valor1,...,campoN=valorN)
            DataTable tabla,t;
            string comandoSQL="",condicion="";
            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;
            OleDbCommand CSelect;
            Type tipo;

            
            tabla = fila.Table;
            comandoSQL = "Select * from " + Tabla + " where (";
            if (campos == null) //se usan todos los campos de la fila
            {
                foreach (DataColumn c in tabla.Columns)
                {
                    tipo = c.GetType();
                    switch(tipo.ToString())
                    {
                        case "System.String":
                            condicion = c.ColumnName + "=" + "'" + Convert.ToString(fila[c.ColumnName]) + "'" + " AND ";
                            break;
                    }
                    comandoSQL = comandoSQL + condicion;
                }

                //quitamos el AND del final
                comandoSQL = comandoSQL.Substring(0, comandoSQL.Length - 3);
                comandoSQL = comandoSQL + ")";
            }
            else //se usan los campos indicados en campos
            {
                foreach (string s in campos)
                {
                    tipo = fila[s].GetType();
                    switch(tipo.ToString())
                    {
                        case "System.String": 
                            condicion = s + "=" + "'" + Convert.ToString(fila[s]) + "'" + " AND ";
                            break;
                    }
                    comandoSQL = comandoSQL + condicion;
                }
                //quitamos el AND del final
                comandoSQL = comandoSQL.Substring(0, comandoSQL.Length - 4);
                comandoSQL = comandoSQL + ")";
            }


            //Ejecutar el comando select
            if (this.ProbarConexion() == true)
            {

                //crear objeto conexion y asignarle la cadena de conexion
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OrigenDatos + ";Persist Security Info=False"; ;

                //Crear comando CSelect y asignarle el objeto conexion
                CSelect = new OleDbCommand();
                CSelect.Connection = Conexion;

                //Crear adaptador y asignarle el comando select
                Adaptador = new OleDbDataAdapter();
                Adaptador.SelectCommand = CSelect;
                //Usar el adaptador para llenar el dataset almacen con las tablas que gestionan los artistas
                t = new DataTable();

                CSelect.CommandType = CommandType.Text;

                CSelect.CommandText = comandoSQL;
                Adaptador.Fill(t);


                CSelect.Dispose();
                Conexion.Dispose();
                Adaptador.Dispose();

                ResultOp = false;
                if (t != null)
                {
                    if(t.Rows.Count>=1)
                        this.ResultOp = true;
                }     
            }

            return ResultOp;
        }*/

        /*public override DataRow Esta(string Tabla, string campo,UInt32 IdClave)
        {
            
            OleDbConnection Conexion;
            OleDbDataAdapter Adaptador;
            OleDbCommand CSelect;
            DataTable t = null;
            DataRow f=null;

            

            this.ResultOp = false;
            if (this.ProbarConexion() == true)
            {

                //crear objeto conexion y asignarle la cadena de conexion
                Conexion = new OleDbConnection();
                Conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + OrigenDatos + ";Persist Security Info=False"; ;

                //Crear comando CSelect y asignarle el objeto conexion
                CSelect = new OleDbCommand();
                CSelect.Connection = Conexion;

                //Crear adaptador y asignarle el comando select
                Adaptador = new OleDbDataAdapter();
                Adaptador.SelectCommand = CSelect;
                //Usar el adaptador para llenar el dataset almacen con las tablas que gestionan los artistas
                t = new DataTable();

                CSelect.CommandType = CommandType.Text;

                CSelect.CommandText =  "select * from " + Tabla + " where " + campo + "=" + IdClave.ToString();
                Adaptador.Fill(t);

                CSelect.Dispose();
                Conexion.Dispose();
                Adaptador.Dispose();

                if (t != null)  
                {
                    if (t.Rows.Count >= 1)
                        f = t.Rows[0];
                }

                this.ResultOp = true;
            }

            return f;
        }*/
    
    
    }
}
